package com.lwl.java8.chapter5;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.junit.Before;
import org.junit.Test;

import com.alibaba.fastjson.JSON;
import com.lwl.java8.chapter4.Dish;

public class Chapter5Test {
	List<Transaction> transactions;
	
	@Before
	public void before(){
		
		Trader raoul = new Trader("Raoul", "Cambridge");
		Trader raoul2 = new Trader("Raoul", "Cambridge");
		Trader mario = new Trader("Mario","Milan");
		Trader alan = new Trader("Alan","Cambridge");
		Trader brian = new Trader("Brian","Cambridge");
		
		transactions = Arrays.asList(
			new Transaction(brian, 2011, 300),
			new Transaction(raoul2, 2012, 1000),
			new Transaction(raoul, 2011, 400),
			new Transaction(mario, 2012, 710),
			new Transaction(mario, 2012, 700),
			new Transaction(alan, 2012, 950)
		);
	}
	

	List<Dish> menu;
	@Before
	public void before1() {
		menu = Arrays.asList(new Dish("chicken", false, 800, Dish.Type.MEAT), new Dish("chicken", false, 700, Dish.Type.MEAT),
				new Dish("chicken", false, 400, Dish.Type.MEAT), new Dish("chicken", true, 530, Dish.Type.OTHER),
				new Dish("chicken", true, 350, Dish.Type.OTHER), new Dish("chicken", true, 120, Dish.Type.OTHER),
				new Dish("chicken", true, 550, Dish.Type.OTHER), new Dish("chicken", false, 300, Dish.Type.FISH),
				new Dish("chicken", false, 450, Dish.Type.FISH));
	}
	
	//找出2011年的所有交易并按交易额排序（从低到高）
	@Test
	public void test1() {
		List<Transaction> collect = transactions.stream().filter(item->item.getYear() == 2011)
		.sorted(Comparator.comparing(Transaction::getValue))
		.collect(Collectors.toList());
		for (Transaction transaction : collect) {
			System.out.println(JSON.toJSONString(transaction));
		}
	}
	
	//交易员都在哪些不同的城市工作过
	@Test
	public void test2() {
		
		List<String> citys = transactions.parallelStream()
		.map(item->item.getTrader().getCity())
		.distinct()
		.collect(Collectors.toList());
		for (String city : citys) {
		    System.out.println(city);	
		}
	}
	
	//查找所有来自于剑桥的交易员，并按姓名排序
	@Test
	public void test3(){
		 List<Trader> traders = transactions.stream()
		.filter(item->item.getTrader().getCity().equals("Cambridge"))
		.map(item->item.getTrader())
		.distinct()
		.sorted(Comparator.comparing(Trader::getName))
		.collect(Collectors.toList());
		for (Trader trader : traders) {
			System.out.println(trader.toString());
		}
	}
	
	
	/*返回所有交易员的姓名字符串,并按照字母顺序排序
	 * 请注意，此解决方案效率不高（所有字符串都被反复连接，每次迭代的时候都要建立一个新的 String 对象）
    */	
	@Test
	public void test4() {
		String reduce = transactions.stream()
		.map(item->item.getTrader().getName())
		.distinct()
		.sorted()
		.reduce("",(n1,n2)->n1 +" "+ n2);
		System.out.println(reduce);
	}
	
	// joining其内部会用到 StringBuilder
	@Test
	public void test5() {
		String reduce = transactions.stream()
		.map(item->item.getTrader().getName())
		.distinct()
		.sorted()
		.collect(Collectors.joining(" "));
		System.out.println(reduce);
	}
	
	/*
	 * 有没有交易员是在米兰工作的
	 */
	@Test
	public void test6() {
		boolean anyMatch = transactions.parallelStream()
		.anyMatch(item-> item.getTrader().getCity().equals("Milan"));
		System.out.println(anyMatch);
	}
	
	//打印生活在剑桥的交易员的所有交易额
	@Test
	public void test7(){
		transactions.stream()
		.filter(a->a.getTrader().getCity().equals("Cambridge"))
		.map(Transaction::getValue)
		.forEach(System.out::println);
	}
	
	//交易中最高的交易额是多少
	@Test
	public void test8(){
		Optional<Transaction> smallestTransaction = transactions.stream()
		.reduce((t1,t2)->t1.getValue() < t2.getValue() ? t1 : t2);
		if(smallestTransaction.isPresent()){
			System.out.println(smallestTransaction.get().getValue());
		}
		
		Optional<Transaction> min = transactions.stream().min(Comparator.comparing(Transaction::getValue));
		if(min.isPresent()){
			System.out.println(min.get().getValue());
		}
		
		Optional<Transaction> max = transactions.stream().max(Comparator.comparing(Transaction::getValue));
		if(max.isPresent()){
			System.out.println(max.get().getValue());
		}
	}
	
	@Test
	public void test9() {
		int sum = menu.stream().mapToInt(Dish::getCalories).sum();
		System.out.println(sum);
		
		IntStream intStream = menu.stream().mapToInt(Dish::getCalories);
		Stream<Integer> stream = intStream.boxed();
	}
	
	@Test
	public void test10() {
		IntStream intStream = IntStream.range(0, 100).filter(n-> n % 2 == 0);
		System.out.println(intStream.count());
		
		Stream<int[]> flatMap = IntStream.rangeClosed(1, 100).boxed()
		    .flatMap(a->IntStream.rangeClosed(a, 100)
				.filter(b->Math.sqrt(a*a + b*b) % 1 == 0)
				.mapToObj(b->new int[]{a,b,(int)Math.sqrt(a*a + b*b)})
			);
		flatMap.limit(3).forEach(t->System.out.println(t[0] + ", " + t[1] + ", " + t[2]));
	
		Stream<double[]> pythagoreanTriples2 =
				IntStream.rangeClosed(1, 100).boxed()
				.flatMap(a ->
				IntStream.rangeClosed(a, 100)
				.mapToObj(
				b -> new double[]{a, b, Math.sqrt(a*a + b*b)})
				.filter(t -> t[2] % 1 == 0));
	}
	
	@Test
	public void test11() {
		//由值创建流
		Stream.of("Java 8 ", "Lambdas ", "In ", "Action")
		.map(String::toUpperCase)
		.forEach(System.out::println);
		
		//由数组创建流
		int[] numbers = {2, 3, 5, 7, 11, 13};
		int sum = Arrays.stream(numbers).sum();

	}
	
	
	
	
	
	
	
	
	
	
	
	

}
